//
//  ViewController.m
//  BabyBluetoothOSDemo
//
//  Created by liuyanwei on 15/9/6.
//  Copyright (c) 2015年 liuyanwei. All rights reserved.
//

#import "ViewController.h"
#import "BabyBluetooth.h"
#import "NSControl+Block.h"
#import "BLEDevice.h"


static NSString* NameCellID = @"NameCellID";
static NSString* DescCellID = @"DescCellID";
static NSString* OtherCellID = @"OtherCellID";
static NSString* HandleCellID = @"HandleCellID";

@interface ViewController ()<NSTableViewDelegate, NSTableViewDataSource>

@property (nonatomic, strong) NSMutableArray<BLEDevice*> *peripherals;
@property (weak) IBOutlet NSTableView *tableView;
@property (weak) IBOutlet NSButton *scanButton;
@property (weak) IBOutlet NSProgressIndicator *scanProgressIndicator;

@end

@implementation ViewController{
    BabyBluetooth *baby;
    
}


- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    
    self.peripherals = [NSMutableArray new];
    //初始化BabyBluetooth 蓝牙库
    baby = [BabyBluetooth shareBabyBluetooth];
    //设置蓝牙委托
    [self babyDelegate];
    baby.scanForPeripherals().
    connectToPeripherals().
    discoverServices().
//    discoverCharacteristics().
//    readValueForCharacteristic().
//    discoverDescriptorsForCharacteristic().
//    readValueForDescriptors().
    begin();
    
    [self.scanProgressIndicator startAnimation:nil];
}


//蓝牙网关初始化和委托方法设置
- (void)babyDelegate{
    
    __weak typeof(baby) weakBaby = baby;
    __weak typeof(self) weakSelf = self;
    
    //设置扫描到设备的委托
    [baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
        NSLog(@"搜索到了设备:%@",peripheral.name);
        BLEDevice* device = [BLEDevice new];
        device.peripheral = peripheral;
        device.advertisementData = advertisementData;
        device.RSSI = RSSI;
        if (![weakSelf.peripherals containsObject:device]) {
            [weakSelf.peripherals addObject:device];
            [weakSelf.tableView reloadData];
        }
    }];
    
    //设置查找设备的过滤器
    //  Peripherals 周边设备
    [baby setFilterOnDiscoverPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
        //设置查找规则是名称大于1 ， the search rule is peripheral.name length > 2
        if (peripheralName.length >1) {
            return YES;
        }
        return NO;
    }];
    
    //连接过滤器
    [baby setFilterOnConnectToPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
//       //这里的规则是：连接第一个设备
//        if (isFirst) {
//            isFirst = NO;
//            return YES;
//        }
        //这里的规则是：连接第一个P打头的设备
        if(weakSelf.peripherals){
            __block BLEDevice * device = nil;
            [weakSelf.peripherals enumerateObjectsUsingBlock:^(BLEDevice * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                if (obj.peripheral.name == peripheralName && obj.status == BLEDeviceStatusConnecting) {
                    device = obj;
                    *stop = YES;
                }
            }];
            if (device) {
                return YES;
            }
        }
        return NO;
    }];
    
    //设置设备连接成功的委托
    [baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) {
        //设置连接成功的block
        NSLog(@"设备：%@--连接成功",peripheral.name);
        //停止扫描
        [weakBaby cancelScan];
        BLEDevice *device = [weakSelf findDeviceByName:peripheral.name];
        if (device) {
            if (device.status != BLEDeviceStatusConnecting) {
                NSLog(@"⚠️警告，状态不正常");
            }
            device.status = BLEDeviceStatusConnected;
        }
    }];
    
    //设置发现设备的Services的委托
    [baby setBlockOnDiscoverServices:^(CBPeripheral *peripheral, NSError *error) {
        for (CBService *service in peripheral.services) {
            NSLog(@"搜索到服务:%@",service.UUID.UUIDString);
        }
    }];
    //设置发现设service的Characteristics的委托
    [baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        NSLog(@"===service name:%@",service.UUID);
        for (CBCharacteristic *c in service.characteristics) {
            NSLog(@"charateristic name is :%@",c.UUID);
        }
    }];
    //设置读取characteristics的委托
    [baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
    }];
    //设置发现characteristics的descriptors的委托
    [baby setBlockOnDiscoverDescriptorsForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
        NSLog(@"===characteristic name:%@",characteristic.service.UUID);
        for (CBDescriptor *d in characteristic.descriptors) {
            NSLog(@"CBDescriptor name is :%@",d.UUID);
        }
    }];
    //设置读取Descriptor的委托
    [baby setBlockOnReadValueForDescriptors:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) {
        NSLog(@"Descriptor name:%@ value is:%@",descriptor.characteristic.UUID, descriptor.value);
    }];
    
    
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];
    
    
}

#pragma mark - NSTableViewDelegate, NSTableViewDataSource
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    return self.peripherals.count;
}

///* This method is required for the "Cell Based" TableView, and is optional for the "View Based" TableView. If implemented in the latter case, the value will be set to the view at a given row/column if the view responds to -setObjectValue: (such as NSControl and NSTableCellView). Note that NSTableCellView does not actually display the objectValue, and its value is to be used for bindings. See NSTableCellView.h for more information.
// */
//- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
//{
//
//}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    NSString *Identifier = nil;
    if (tableColumn == tableView.tableColumns[0]) {
        Identifier = NameCellID;
    } else if (tableColumn == tableView.tableColumns[1]) {
        Identifier = DescCellID;
    } else if (tableColumn == tableView.tableColumns[2]) {
        Identifier = OtherCellID;
    } else if (tableColumn == tableView.tableColumns[3]) {
        Identifier = HandleCellID;
    }
    
    
    NSTableCellView* cell = (NSTableCellView*)[tableView makeViewWithIdentifier:Identifier owner:nil];
    if (cell) {
        BLEDevice* device = self.peripherals[row];
        if (tableColumn == tableView.tableColumns[0]) {
            cell.textField.stringValue = device.peripheral.name;
        } else if (tableColumn == tableView.tableColumns[1]) {
            cell.textField.stringValue = [[device.advertisementData description] stringByReplacingOccurrencesOfString:@"\n" withString:@""];
        } else if (tableColumn == tableView.tableColumns[2]) {
            cell.textField.stringValue = [device.RSSI stringValue];
        } else if (tableColumn == tableView.tableColumns[3]) {
            NSButton *button = [cell viewWithTag:100];
            [button setTapBlock:^(NSControl * _Nonnull control) {
                NSLog(@"连接 %@", device.peripheral);
                [self connectToDevice:device];
            }];
        }
    }
    return cell;
}

- (void)connectToDevice:(BLEDevice*)device {
    device.status = BLEDeviceStatusConnecting;
    [baby.centralManager connectPeripheral:device.peripheral options:nil];
}

- (IBAction)scanDevice:(id)sender {
    
}


#pragma mark - 私有方法
- (BLEDevice*)findDeviceByName:(NSString*)name {
    __block BLEDevice * device = nil;
    [self.peripherals enumerateObjectsUsingBlock:^(BLEDevice * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj.peripheral.name == name) {
            device = obj;
            *stop = YES;
        }
    }];
    return device;
}

@end

